package com.own.business.irs.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.own.business.irs.constant.Constants;
import com.own.business.irs.model.UserInfoModel;
import com.own.business.irs.property.IrsProperty;
import com.own.business.irs.service.ZlbAuthService;
import com.own.business.irs.util.IrsUtil;
import com.own.component.common.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

/**
 * ZlbWechatAuthServiceImpl
 *
 * @author jie.chen
 * @date 2022-03-30 15:49
 */
@Slf4j
@Component
public class ZlbWechatAuthServiceImpl implements ZlbAuthService {

    @Resource
    private RestTemplateBuilder restTemplateBuilder;

    private RestTemplate restTemplate;

    @Resource
    private IrsProperty irsProperty;
    @Resource
    private IrsUtil irsUtil;

    @PostConstruct
    void init() {
        restTemplate = restTemplateBuilder.build();
    }

    /**
     * 根据票据id获取token
     *
     * @param ticketId 票据id
     * @return token
     */
    @Override
    public String getTokenByTicketId(String ticketId) {
        // 获取请求头信息
        var headers = getHttpHeaders(irsProperty.getLogin().getUrlWechatTicket());
        var body = new JSONObject();
        body.put("appId", irsProperty.getAppId());
        body.put("ticketId", ticketId);
        // 构造信息
        var request = new HttpEntity<>(body, headers);
        // 请求数据
        var response = restTemplate.postForEntity(irsProperty.getLogin().getUrlWechatTicket(), request, String.class);
        return checkResponse(response).getJSONObject("data").getString("accessToken");
    }

    /**
     * 根据token获取用户信息
     *
     * @param token token
     * @return 用户信息
     */
    @Override
    public UserInfoModel getUserInfoByToken(String token) {
        // 获取请求头信息
        var headers = getHttpHeaders(irsProperty.getLogin().getUrlWechatUserInfo());
        var body = new JSONObject();
        body.put("token", token);
        // 构造信息
        var request = new HttpEntity<>(body, headers);
        // 请求数据
        var response = restTemplate.postForEntity(irsProperty.getLogin().getUrlWechatUserInfo(), request, String.class);
        return new UserInfoModel().ofWechat(checkResponse(response).getJSONObject("data").getJSONObject("personInfo"));
    }

    /**
     * 验证响应信息
     *
     * @param response 响应信息
     * @return 响应信息
     */
    private JSONObject checkResponse(ResponseEntity<String> response) {
        if (!response.getStatusCode().is2xxSuccessful()) {
            // 请求失败
            throw new BusinessException("status:" + response.getStatusCodeValue() + " " + response.getBody());
        }
        var result = JSON.parseObject(response.getBody());
        if (result != null && result.containsKey("errorCode") && result.getString("errorCode") != null && !result.getBooleanValue("success")) {
            // 业务错误
            throw new BusinessException(result.toString());
        }
        return result;
    }

    /**
     * 获取请求头信息
     *
     * @param url 请求地址
     * @return 请求头信息
     */
    private HttpHeaders getHttpHeaders(String url) {
        var res = irsUtil.sign(url, "POST");
        // 设置请求头
        var headers = new HttpHeaders();
        headers.add(Constants.X_BG_HMAC_ACCESS_KEY, res.getAccessKey());
        headers.add(Constants.X_BG_HMAC_ALGORITHM, res.getAlgorithm());
        headers.add(Constants.X_BG_HMAC_SIGNATURE, res.getSignature());
        headers.add(Constants.X_BG_DATE_TIME, res.getDateTime());
        return headers;
    }

}
